﻿define(function (require, exports, module) {
    var Config = require('util/config');
    var ImageStorage;

    var m_stage = new Kinetic.Stage({
        container: 'container',
        width: Config.settings.WIDTH,
        height: Config.settings.HEIGHT
    });

    exports.initialize = function (imageStorage) {
        ImageStorage = imageStorage;
    };

    exports.draw = function () {
        m_stage.draw();
    };

    exports.add = function (layer) {
        m_stage.add(layer);
    };

    exports.clear = function () {
        m_stage.removeChildren();
    };

    exports.get = function (id) {
        return m_stage.get(id);
    };

    exports.createLayer = function (options) {
        options || (options = {});
        var layer = new Kinetic.Layer(options);
        return layer;
    };

    exports.createImage = function (options) {
        if (options.hasOwnProperty('image')) {
            options.hasOwnProperty('width') || (options.width = options.image.width);
            options.hasOwnProperty('height') || (options.height = options.image.height);
        }
        var image = new Kinetic.Image(options);
        return image;
    };

    exports.createImageAsync = eval(Wind.compile('async', function (options) {
        options.image = $await(ImageStorage.getAsync(options.image));
        var image = this.createImage(options);
        return image;
    }));

    function loadImageTask(src) {
        return Wind.Async.Task.create(function (t) {
            var img = new Image();
            $(img).load(function () {
                m_cache[src] = img;
                t.complete('success', { success: true, img: img });
            }).error(function () {
                t.complete('success', { success: false });
            }).attr('src', src);
        });
    };

    exports.craeteImageWithBoxAnimation = function (options) {
        var image = this.createImage(options);
        this.setNodeWithBoxAnimation(image);
        return image;
    };

    exports.createImageWithBoxAnimationAsync = eval(Wind.compile('async', function (options) {
        var image = $await(this.createImageAsync(options));
        this.setNodeWithBoxAnimation(image);
        return image;
    }));

    exports.createText = function (options) {
        options || (options = {});
        var config = $.extend({
            fontFamily: Config.settings.FONT_FAMILY,
            fontSize: Config.settings.FONT_SIZE,
            fill: Config.settings.FONT_COLOR
        }, options);
        return new Kinetic.Text(config);
    };

    exports.createRect = function (options) {
        options || (options = {});
        var config = $.extend({ width: Config.settings.WIDTH, height: Config.settings.HEIGHT }, options);
        return new Kinetic.Rect(config);
    };

    exports.createRectWithBoxAnimation = function (options) {
        var rect = this.createRect(options);
        this.setNodeWithBoxAnimation(rect);
        return rect;
    };

    exports.createRectAsync = eval(Wind.compile('async', function (options) {
        options.fillPatternImage = $await(ImageStorage.getAsync(options.fillPatternImage));
        return this.createRect(options);
    }));

    exports.setNodeWithBoxAnimation = function (node) {
        node.setAttrs({ stroke: 'rgba(0, 0, 0, 0)', strokeWidth: 2 });

        node.on('mouseover', function () {
            var point = 255;
            this.overAnimation = new Kinetic.Animation(function (frame) {
                if (point == 255)
                    node.setStroke('rgb(0, 255, 0)');
                else if (point == 155)
                    node.setStroke('rgb(0, 128, 0)');
                (point -= 4) < 128 && (point = 255);
            }, node.getLayer());
            this.overAnimation.start();
        });

        node.on('mouseout', function () {
            this.setStroke('rgba(0, 0, 0, 0)');
            this.overAnimation.stop();
            this.getLayer().draw();
        });
    };

    exports.removeNodeBoxAnimation = function (node) {
        node.setStroke('rgba(0, 0, 0, 0)');
        node.hasOwnProperty('overAnimation') && node.overAnimation.stop();
        node.getLayer().draw();
    };

    exports.createGroup = function (options) {
        options || (options = {});
        var config = $.extend({ width: Config.settings.WIDTH, height: Config.settings.HEIGHT }, options);
        return new Kinetic.Group(config);
    };
});